/*
 * CUDAAESEncrypter.cpp
 *
 *  Created on: Jun 23, 2010
 *      Author: Lukasz Spintzyk
 */

#include "ph.h"
#include "CUDAAESEncrypter.h"
#include "CudaAESFast.h"
#include "cudaUtils.h"
// TODO AES ENCRYPT INIT

CUDAAESEncrypter::CUDAAESEncrypter(BigInteger& init_vector, byte* key)
	:AESEncrypter(init_vector, key)
	,d_cuMem(new CudaMemoryManager())
	,host_IVMemory(0)
	,device_IVMemory(NULL)
	,deviceIVmemorySize(0)
{
	try{
		aesFastCipherInit();
		assert(sizeof(d_key.rd_key) == s_expandedKeySize);
		deviceMemExpandedKey =(uint32_t*) d_cuMem->malloc(s_expandedKeySize);
		d_cuMem->copy((byte*)deviceMemExpandedKey, (byte*)d_key.rd_key, s_expandedKeySize);
	}
	catch (CUDAException& e)
	{
		std::cerr << e.what();
	}
}

CUDAAESEncrypter::~CUDAAESEncrypter()
{
	delete d_cuMem;
	// TODO Auto-generated destructor stub
}

void* CUDAAESEncrypter::encrypt(const void* inbuffer, uint32_t size, uint32_t nr)
{
	BigInteger ivc = iv;
	ivc = ivc + nr;
	allocDeviceIVMemory(size);
	aesEncryptIVBlocksBig(	  (byte*)inbuffer,
						  device_IVMemory,
						  host_IVMemory,
						  size,
						  deviceMemExpandedKey,
						  ivc);
	return host_IVMemory;

}

void* CUDAAESEncrypter::decrypt(const void* buffer, uint32_t size, uint32_t nr)
{
	return encrypt(buffer, size, nr);
}

void CUDAAESEncrypter::allocDeviceIVMemory(uint32_t size)
{
	if (size > deviceIVmemorySize)
	{
		if (device_IVMemory)
		{
			d_cuMem->free(device_IVMemory);
		}
		if (host_IVMemory)
		{
			delete[] host_IVMemory;
		}
		device_IVMemory = d_cuMem->malloc(size);
		host_IVMemory = new byte[size];
		deviceIVmemorySize = size;
	}
}

